package com.xiaobange.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import com.xiaobange.constants.RedisKey;
import com.xiaobange.entity.Role;
import com.xiaobange.mapper.RoleMapper;
import com.xiaobange.mapper.RolePermissionMapper;
import com.xiaobange.utils.PasswordUtil;
import com.xiaobange.utils.RedisCache;
import com.xiaobange.vo.ResultResponse;
import com.xiaobange.entity.User;
import com.xiaobange.exception.ServiceException;
import com.xiaobange.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author banji
 * @description 针对表【sys_user(系统用户表)】的数据库操作Service实现
 * @createDate 2025-04-24 17:57:21
 */
@Service
public class UserLoginServiceImpl {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 生成系统用户
     *
     * @param user 用户信息
     * @return 结果
     */

    public ResultResponse<Map<String, String>> register(User user) {
        //1.查询系统用户是否存在
        User mapperLoginNameInfo = userMapper.selectLoginName(user.getLoginName());
        if (mapperLoginNameInfo != null) {
            throw new ServiceException("用户名已存在");
        }
        //2.对数据进行填充
        //获得当前操作者ID
        String loginId = StpUtil.getLoginId().toString();
        user.setCreateBy(loginId); // TODO 后期要根据登录用户来决定
        //创建时间
        user.setCreateTime(LocalDateTime.now());

//        String text = null;
//        //是否开启生成复制密码逻辑
//        if (false) {
//            //生成一个随机密码
//            text = genRandomPassword(12);
//        } else {
//            text = "123456";
//        }
        //对密码进行加密，并设置密码
        user.setPassword(user.getPassword());
        //设置登录账号，登录账号就是用户的手机号
        //user.setLoginName(user.getPhoneNumber());
        //将数据插入数据库
        int i = userMapper.insertUser(user);
        if (i <= 0) throw new ServiceException("创建系统用户失败!");
        //返回结果
        Integer userId = user.getUserId();
        Map<String, String> map = new HashMap<>();
        map.put("loginName", user.getLoginName());
        map.put("password", user.getPassword());
        map.put("username", user.getUserName());
        return ResultResponse.success(map);
    }


    public ResultResponse login(String loginName, String password) {
        //1.根据用户名查询用户是否存在
        User user = userMapper.selectLoginName(loginName);
        //2.判断用户是否存在
        if (user == null || "1".equals(user.getDelFlag())) {
            throw new ServiceException("用户不存在!");
        }
        //3.判断用户的输入的密码是否正确
        String decode = PasswordUtil.passwordDecode(user.getPassword());
        if (!password.equals(decode)) {
            throw new ServiceException("密码错误!");
        }
        //4.判断用户的状态是否正常
        if (!"0".equals(user.getStatus())) {
            throw new ServiceException("您已被限制登录!");
        }
        //查询用户对应的角色
        if (user.getRoleId() == null) {
            throw new ServiceException("未查询到您的角色权限，请联系管理员~~~");
        }
        Role role = roleMapper.selectById(user.getRoleId().toString());
        if (role == null) {
            throw new ServiceException("未查询到您的角色权限，请联系管理员~~~");
        }
        //查询用户对应的权限标识符
        List<String> rolePermissionList = rolePermissionMapper.selectPermissions(role.getRoleId().toString(), user.getUserId().toString());
        //将用户对应的权限保存到Redis缓存中
        if (rolePermissionList != null) {
            redisCache.setCacheList(RedisKey.USER_PERMISSION_LIST + user.getUserId(),rolePermissionList);
            redisCache.expire(RedisKey.USER_PERMISSION_LIST + user.getUserId(),60, TimeUnit.MINUTES);//设置过期时间为60分钟
        }
        //5.登录成功 将登录状态保存到Redis 返回登录状态
        SaLoginParameter saLoginParameter = new SaLoginParameter();
        saLoginParameter.setExtra("role",role.getRoleKey());
        StpUtil.login(user.getUserId(),saLoginParameter);
        //获取用户的token
        String tokenValue = StpUtil.getTokenValue();
        // 将token保存到Redis  TODO 后续这里要设置过期时间
        redisCache.setCacheObject(RedisKey.USER_LOGIN_TOKEN_KEY + user.getUserId() , tokenValue);
        //返回token给前端
        user.setPassword(null);
        user.setRoles(role.getRoleKey());
        Map<String,Object> map = new HashMap<>();
        map.put("token",tokenValue);
        map.put("userInfo",user);
        return ResultResponse.success(map);
    }


    /**
     * 退出登录
     */

    public void logout() {
        //删除吊Redis中的登录数据
        try {
            redisCache.deleteObject(RedisKey.USER_LOGIN_TOKEN_KEY + StpUtil.getLoginId());
            redisCache.deleteObject(RedisKey.USER_PERMISSION_LIST + StpUtil.getLoginId());
            redisCache.deleteObject(RedisKey.USER_INFO_ID_KEY + StpUtil.getLoginId());
            StpUtil.logout();
        } catch (Exception e) {
            throw new ServiceException("错误请求!");
        }
    }

    /**
     * 生成指定长度的随机密码
     *
     * @param length 指定长度
     * @return 结果
     */
    private String genRandomPassword(int length) {
        String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                + "abcdefghijklmnopqrstuvwxyz"
                + "0123456789"
                + "()[]{}.,!?@#$%^&*_-+=<>|";
        StringBuilder password = new StringBuilder();
        Random random = new Random();
        for (int i = length; i > 0; i--) {
            int index = random.nextInt(text.length());
            password.append(text.charAt(index));
        }
        return password.toString();
    }


}




